﻿/*
 * Description: Wnd text fetch helper.
 */
#include <Windows.h>
#include <set>
#include <vector>
#include <unordered_map>
#include <string>
#include "performance/perf_constants.h"

using namespace PERF;

namespace {

constexpr const auto WNDTEXT_MAX_LENGTH = 2560;

const std::vector<std::wstring> WNDTEXT_SUFFIXS = { L"Word",           L"Excel",           L"PowerPoint",
                                                    L"Microsoft Word", L"Microsoft Excel", L"Microsoft PowerPoint" };
const std::set<std::wstring> IGNORED_WND_TEXT = { L"正在打开 - Word",
                                                  L"正在打开 - Excel",
                                                  L"正在打开 - PowerPoint",
                                                  L"Word",
                                                  L"Excel",
                                                  L"PowerPoint",
                                                  L"正在打开 - Microsoft Word",
                                                  L"正在打开 - Microsoft Excel",
                                                  L"正在打开 - Microsoft PowerPoint",
                                                  L"Microsoft Word",
                                                  L"Microsoft Excel",
                                                  L"Microsoft PowerPoint" };

BOOL EnumWndProc(HWND hwnd, LPARAM lParam)
{
    std::vector<std::wstring> *wndTexts = reinterpret_cast<std::vector<std::wstring> *>(lParam);
    if (wndTexts == nullptr) {
        return FALSE;
    }
    int wndTextLen = GetWindowTextLengthW(hwnd);
    WCHAR wndText[WNDTEXT_MAX_LENGTH] = { 0 };
    GetWindowTextW(hwnd, wndText, wndTextLen * sizeof(WCHAR) + sizeof(WCHAR));
    std::wstring wndTextStr = wndText;
    wndTexts->emplace_back(wndTextStr);
    return TRUE;
}

bool CheckWndText(const std::wstring &wndText)
{
    if (wndText.size() == 0) {
        return false;
    }
    auto ignoredIt = IGNORED_WND_TEXT.begin();
    while (ignoredIt != IGNORED_WND_TEXT.end()) {
        if (wndText == *ignoredIt) {
            return false;
        }
        ignoredIt++;
    }
    auto suffixIt = WNDTEXT_SUFFIXS.begin();
    while (suffixIt != WNDTEXT_SUFFIXS.end()) {
        if (wndText.find(*suffixIt) != std::wstring::npos) {
            return true;
        }
        suffixIt++;
    }
    return false;
}

}  // namespace

int main()
{
    std::vector<std::wstring> wndTexts;
    HANDLE hWrite = CreateFile(WND_TEXT_PATH, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
    if (hWrite == INVALID_HANDLE_VALUE) {
        return -1;
    }
    EnumWindows(::EnumWndProc, (LPARAM)&wndTexts);
    for (auto wndText : wndTexts) {
        if (!CheckWndText(wndText)) {
            continue;
        }
        std::wstring str = wndText + L"\n";
        DWORD dwLen = wcslen(str.c_str()) * sizeof WCHAR;
        DWORD dwLenWritten = 0;
        WriteFile(hWrite, str.c_str(), dwLen, &dwLenWritten, nullptr);
    }
    CloseHandle(hWrite);
    return 0;
}